#include "MysqlDaoBase.h"
#include "../../log.h"

int MysqlDaoBase::ExecUpdate(const std::string& sql) 
{
    auto conn = acquire();
    if (!conn.get()) return -1;

    if (mysql_query(conn.get(), sql.c_str())) 
    {
        log_error("ExecUpdate Error: {}", mysql_error(conn.get()));
        return -1;
    }
    return mysql_affected_rows(conn.get());
}

std::vector<std::map<std::string, std::string>> MysqlDaoBase::ExecQuery(const std::string& sql) 
{
    auto conn = acquire();
    std::vector<std::map<std::string, std::string>> results;

    if (!conn.get()) return results;

    // 执行 SQL 查询
    if (mysql_query(conn.get(), sql.c_str())) 
    {
        log_error("ExecQuery Error: {}", mysql_error(conn.get()));
        return results;
    }

    // 获取查询结果
    MYSQL_RES* res = mysql_store_result(conn.get());
    if (!res) 
    {
        log_error("mysql_store_result failed: {}", mysql_error(conn.get()));
        return results;
    }

    // 获取结果集中的列数。
    int num_fields = mysql_num_fields(res);
    MYSQL_ROW row;
    // fields：这是一个 MYSQL_FIELD 类型的数组，包含 mysql_fetch_fields 返回结果集中每列的信息。
    MYSQL_FIELD* fields = mysql_fetch_fields(res);

    // mysql_fetch_row 于从结果集 res 中获取下一行数据
    // 如果成功，它返回一个指向包含行数据的 MYSQL_ROW 类型的指针；如果已经到达结果集的末尾或发生错误，则返回 nullptr。
    while ((row = mysql_fetch_row(res))) 
    {
        // record 用于存储当前行的数据 其中键是列名，值是列值。
        std::map<std::string, std::string> record;
        // 遍历当前行的所有列
        for (int i = 0; i < num_fields; i++) {
            // 添加列名和对应的值到 record 中。如果该列为 NULL，则将其视为空字符串 ""
            record[fields[i].name] = row[i] ? row[i] : "";
        }
        results.push_back(std::move(record));
    }

    mysql_free_result(res);
    return results;
}
